using System;
using NUnit.Framework;
using ValidationFramework.Reflection;

namespace ValidationFramework.Tests
{

	[TestFixture]
	public class TypeCacheTest
	{
		
        [TestFixture]
        public new class GetType
        {
            [Test]
            public void NoDuplicateTest()
            {

                TypeCache.Clear();
                var personTypeHandle1 = typeof(TempClass).TypeHandle;
                var personTypeHandle2 = typeof(TempClass).TypeHandle;
                var typeDescriptor1 = TypeCache.GetType(personTypeHandle1);
                var typeDescriptor2 = TypeCache.GetType(personTypeHandle2);
                Assert.AreSame(typeDescriptor1, typeDescriptor2);
                TypeCache.Clear();
            }
            [Test]
            public void Handle()
            {
                TypeCache.Clear();

                var handle = typeof(TempClass).TypeHandle;
                //create a PropertyDescriptor for NumberOfDoors and add a RangeRule to it.  
                var typeDescriptor = TypeCache.GetType(handle);
                Assert.AreEqual(handle, typeDescriptor.RuntimeTypeHandle);
            }
            [Test]
            public void Generic()
            {
                TypeCache.Clear();

                //create a PropertyDescriptor for NumberOfDoors and add a RangeRule to it.  
                var typeDescriptor = TypeCache.GetType<TempClass>();
                Assert.AreEqual(typeof (TempClass).TypeHandle, typeDescriptor.RuntimeTypeHandle);
            }

            public class TempClass{}

        }

       
#if (!WindowsCE)
	    [TestFixture]
		public class GetOrCreatePropertyDescriptor
		{
			public class TempClass
			{
				public string SimplePropertyProperty { get; set; }
			}
			[Test]
			public void Simple()
			{
                var descriptor = TypeCache.GetOrCreatePropertyDescriptor<TempClass>(x => x.SimplePropertyProperty);
                Assert.AreEqual("SimplePropertyProperty", descriptor.Name);
			}
			
		}
		[TestFixture]
		public class GetOrCreateFieldDescriptor
		{
			public class TempClass
			{
				public string tempField;
			}
			[Test]
			public void Simple()
			{
				var descriptor = TypeCache.GetOrCreateFieldDescriptor<TempClass>(x => x.tempField);
                Assert.AreEqual("tempField", descriptor.Name);
			}

		}
#endif

		[TestFixture]
		public class GetRulesForProperty
		{
            public class TempClass
            {
                [RequiredStringRule]
                public string TempProperty
                {
                    get;
                    set;
                }

            }
			[Test]
			public void Handle()
			{
                var list = TypeCache.GetRulesForProperty<RequiredStringRule>("TempProperty", typeof(TempClass).TypeHandle);
				Assert.AreEqual(1, list.Count);
			}
			[Test]
			public void Generic()
			{
                var list = TypeCache.GetRulesForProperty<RequiredStringRule, TempClass>("TempProperty");
				Assert.AreEqual(1, list.Count);
			}




			[Test]
			[ExpectedException(typeof(ArgumentException), ExpectedMessage = "String cannot be empty.\r\nParameter name: propertyName")]
			public void ExceptionEmptyPropertyName()
			{
				TypeCache.GetRulesForProperty<LengthStringRule>("", typeof(TempClass).TypeHandle);
			}


			[Test]
			[ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "Value cannot be null.\r\nParameter name: propertyName")]
			public void ExceptionNullPropertyName()
			{
				TypeCache.GetRulesForProperty<LengthStringRule>(null, typeof(TempClass).TypeHandle);
			}
		}
	}
}